import { WsCode } from "../net/WsUtils"

/**
 * 事件类型
 */
export enum EventType {
    /** 初始化网络 */
    INIT_NET,
}

/**
 * 事件工具类
 */
export default class EventUtils {
    /** 事件map <事件类型, 回调集合> */
    private static _eventMap: Map<EventType | WsCode, Set<Function>> = new Map()
    /** 调用者map <回调函数, 调用者> */
    private static _targetMap: Map<Function, any> = new Map()

    /**
     * 注册事件
     * @param type 事件类型
     * @param callback 回调函数
     * @param target 调用者
     */
    static on(type: EventType | WsCode, callback: Function, target?) {
        let set = this._eventMap.get(type)
        if (!set) {
            set = new Set()
        }

        if (set.has(callback)) {
            cc.warn("重复注册事件：", callback)
            return
        }

        // 更新缓存
        set.add(callback)
        this._eventMap.set(type, set)
        this._targetMap.set(callback, target)
    }

    /**
     * 注销事件
     * @param type 事件类型
     * @param callback 回调函数
     */
    static off(type: EventType | WsCode, callback: Function) {
        let set = this._eventMap.get(type)
        if (set) {
            if (set.has(callback)) {
                set.delete(callback)
            }
        }

        if (this._targetMap.has(callback)) {
            this._targetMap.delete(callback)
        }
    }

    /**
     * 派发事件
     * @param type 事件类型
     * @param args 参数列表
     */
    static emit(type: EventType, ...args) {
        let set = this._eventMap.get(type)
        if (set) {
            set.forEach(callback => {
                let target = this._targetMap.get(callback)
                callback.call(target, ...args)
                return
            });
        }
    }
}